 
import { ABaseDecision } from "GameLoop/DecisionMaking/BaseDecision";
import { fillerConfig } from "GameLoop/WorldState/EntityManager/Entitys/room/spawn/spawnlayout";
import { getRoleConfig } from "utils/constants/bodyconstant";
import { BodyEfficiency } from "utils/creep/bodyEfficiency";
import { BodyUtils } from "utils/creep/bodyutils";
import { Roles } from "utils/creep/setups";
import { generateUniqueId } from "utils/utils";
export const CreepWorkEffect:Record<string,number>=
{
    build:5,
    repair:1,
    upgradeController:1
}
/**
 * 本房间的消费任务决策
 * 维修，建设，升级，填充，日常消费
 */
export class ConsumerCreepsDecision<  T extends "KeepCreep"="KeepCreep"> extends ABaseDecision<T>
{
    // 基本上每次触发任务都需要更新
    public isExpired(event: KeepEvent, region: string): boolean 
    {
        return true;
    }
    public makeTask(event: KeepEvent, region: string): IDecisionCode<T>|false
    {
        const room = Game.rooms[event.region] as Required<Room>;
        const keepTask = room.getTaskByType("KeepCreep")[0];
        if(!keepTask)
        {
            this.WorldGetter.registerNotify(event.region,{
                type:"KeepEvent",
                region:event.region,
                room:event.room
            })
            global.Log.Error(`${event.region} KeepCreep 任务未初始化`);
            throw new Error(`任务未初始化`);
        }
        // 根据统计信息,计算出升级爬，维护爬，填充爬的数量分配
        /**
         * 1.首先计算填充爬
         * 2.计算维修爬,也是worker
         * 3.计算建设爬和升级爬
         * 4.当有site时，升级爬只留一只，其他都给建设爬
         * 5.当没有site时，全都给升级爬,升级爬的数量还关系到运输给升级爬，的运输爬的数量
         */
        // 
        if(!room.memory.stats)
        {
            global.Log.Error(`${event.region} 统计信息未初始化`);
            throw new Error(`统计信息未初始化`);
        }
        let left = _.clone(room.memory.stats?.governable)
        const roomlevel = room.controller?.level as number;
      
        const rolemap:[RoleName,number][]=[];
     
        const filleramount = fillerConfig[roomlevel];
        if(filleramount)
        {
            left = this.getLeftCost(left,roomlevel,"filler",filleramount);
            rolemap.push(["filler",filleramount])
        }
        let carryer=0;
        if(roomlevel>3)
        {
            carryer=1;
            if(roomlevel>=7)
            {
                carryer=2;
            }
            left = this.getLeftCost(left,roomlevel,"carry",carryer);
            rolemap.push(["carry",carryer])
        }

        if(room.find(FIND_CONSTRUCTION_SITES).length>0)
        {
            // upgrader 只留一个余下出worker
            left = this.getLeftCost(left,roomlevel,"upgrader",1);
            const workercount = BodyEfficiency.getMaxCreepAmount(left,roomlevel,"worker","build");
            rolemap.push(["upgrader",1]);
            rolemap.push(["worker",Math.min(workercount,40)]);
        }
        else
        {
            if(room.controller?.level !=8)
            {
                // 全出 upgrader 
                const bodyconfig =  getRoleConfig("upgrader",room.controller?.level);
                const progress =  room.controller.progressTotal-room.controller.progress;
                const leastnum = BodyEfficiency.getCreepCount("upgrader",room.controller.level,WORK,5);
                const upgradenum = BodyEfficiency.calCreepCountByProgress(progress,bodyconfig.body,"upgradeController");
                const upgradercount = BodyEfficiency.getMaxCreepAmount(left,roomlevel,"upgrader","upgradeController");
                rolemap.push(["upgrader",Math.min(upgradercount, Math.max(leastnum,upgradenum))]);
            }
            else
            {
                rolemap.push(["upgrader",1]);
            }
           
             
        }
        for(const e of rolemap)
        {
            const bodyconfig =   getRoleConfig(e[0],roomlevel);
            let idx = keepTask.data.role.findIndex(i=>i[0].Role == e[0]);
            if(idx>=0)
            {
                keepTask.data.role[idx][0].body= bodyconfig.body;
                keepTask.data.role[idx][1] = e[1];
            }
            else
            {
                keepTask.data.role.push([{Role:e[0],body:bodyconfig.body,isAdapt:true},e[1]]);
            }
        }
       
        // 计算，消费的爬数量

        return false

    }
    // 因为每个爬都需要1T发送命令 所以每个爬要额外消耗 1/3个body孵化
    private getLeftCost(left:{energy:number,body:number},level:number,role:RoleName,amount:number)
    {
        const bodyconfig =   getRoleConfig(role,level);
        const bodyparts =  BodyUtils.flatBodyParts(bodyconfig.body); // 
        const rolecost = BodyUtils.calculateSpawnEnergy(bodyparts);
        const energy_cost =  rolecost*amount;
        const body_cost =  BodyUtils.getBodyCountCost(bodyparts,amount);
        return {energy:left.energy- energy_cost,body:left.body-body_cost}
    }
    
}